package cn.tedu.csmall.product.webapi.service;

import cn.tedu.csmall.common.ex.ServiceException;
import cn.tedu.csmall.common.web.JsonResult;
import cn.tedu.csmall.common.web.State;
import cn.tedu.csmall.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.pojo.entity.Category;
import cn.tedu.csmall.pojo.vo.CategoryDetailsVO;
import cn.tedu.csmall.pojo.vo.CategorySimpleListItemVO;
import cn.tedu.csmall.pojo.vo.CategorySimpleVO;
import cn.tedu.csmall.product.service.ICategoryService;
import cn.tedu.csmall.product.webapi.mapper.CategoryMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class CategoryServiceImpl implements ICategoryService {

    @Autowired
    CategoryMapper categoryMapper;

    @Override
    @Transactional
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) throws ServiceException {
        // 从参数中取出尝试添加的类别的名称
        String name = categoryAddNewDTO.getName();
        // 调用categoryMapper.getByName()方法查询
        CategorySimpleVO queryResult = categoryMapper.getByName(name);
        // 判断查询结果是否不为null
        if (queryResult != null) {
            // 是：抛出ServiceException
            throw new ServiceException(State.ERR_CATEGORY_NAME_DUPLICATE,
                    "添加类别失败，名称（" + name + "）已存在！");
        }

        // 从参数中取出父级类别的id：parentId
        Long parentId = categoryAddNewDTO.getParentId();
        // 判断parentId是否为0，当前尝试新增的类别的depth默认为1
        Integer depth = 1;
        CategorySimpleVO parentCategory = null;
        if (parentId != 0) {
            // 否：此次尝试添加的不是一级类别，则应该存在父级类别，调用categoryMapper.getById()方法查询父级类别的信息
            parentCategory = categoryMapper.getById(parentId);
            // -- 判断查询结果是否为null
            if (parentCategory == null) {
                // -- 是：抛出ServiceException
                throw new ServiceException(State.ERR_CATEGORY_NOT_FOUND,
                        "添加类别失败，父级类别不存在！");
            }
            // -- 否：当前depth >>> 父级depth + 1
            depth = parentCategory.getDepth() + 1;
        }

        // 创建Category对象
        Category category = new Category();
        // 调用BeanUtils.copyProperties()将参数对象中的属性值复制到Category对象中
        BeanUtils.copyProperties(categoryAddNewDTO, category);
        // 补全Category对象中的属性值：depth >>> 前序运算结果
        category.setDepth(depth);
        // 补全Category对象中的属性值：enable >>> 1（默认即启用）
        category.setEnable(1);
        // 补全Category对象中的属性值：isParent >>> 0
        category.setIsParent(0);
        // 补全Category对象中的属性值：gmtCreate, gmtModified >>> LocalDateTime.now()
        LocalDateTime now = LocalDateTime.now();
        category.setGmtCreate(now);
        category.setGmtModified(now);
        // 调用categoryMapper.insert(Category)插入类别数据，获取返回的受影响的行数
        int rows = categoryMapper.insert(category);
        // 判断返回的受影响的行数是否不为1
        if (rows != 1) {
            /// 是：抛出ServiceException
            throw new ServiceException(State.ERR_INSERT,
                    "添加类别失败，服务器忙（" + State.ERR_INSERT.getValue() + "），请稍后再次尝试！");
        }

        // 判断父级类别的isParent是否为0
        // 以下判断条件有部分多余，但不会报错
        if (parentId != 0 && parentCategory != null && parentCategory.getIsParent() == 0) {
            // 是：调用categoryMapper.updateIsParentById()方法，将父级类别的isParent修改为1，获取返回的受影响的行数
            rows = categoryMapper.updateIsParentById(parentId, 1);
            // 判断返回的受影响的行数是否不为1
            if (rows != 1) {
                // 是：抛出ServiceException
                throw new ServiceException(State.ERR_UPDATE,
                        "添加类别失败，服务器忙（" + State.ERR_UPDATE.getValue() + "），请稍后再次尝试！");
            }
        }
    }

    @Override
    public CategoryDetailsVO getDetailsById(Long id) {
        return null;
    }

    @Override
    public List<CategorySimpleListItemVO> listByParentId(Long parentId) {
        return null;
    }

    @Override
    public void preloadCache() {

    }


    //    1. 根据类别的id，禁用对应的类别
//- 类别不存在时抛出异常
//- 类别已禁用时抛出异常
    public JsonResult disabledById(Integer id) throws ServiceException {
        Integer enable=categoryMapper.selectEnableById(id);
        if (enable==null){
            throw new ServiceException(State.ERR_UPDATE, "禁用失败，该分类不存在！");
        }
        if (enable==0){
            throw new ServiceException(State.ERR_UPDATE, "禁用失败，该分类已禁用！");
        }
        categoryMapper.upEnableById(id);
        return JsonResult.ok("禁用成功");
    }
    //2. 根据类别的id，启用对应的类别
//- 类别不存在时抛出异常
//- 类别已启用时抛出异常
    public JsonResult stateById(Integer id) throws ServiceException {
        Integer enable=categoryMapper.selectEnableById(id);
        if (enable==null){
            throw new ServiceException(State.ERR_UPDATE, "启用失败，该分类不存在！");
        }
        if (enable==1){
            throw new ServiceException(State.ERR_UPDATE, "启用失败，该分类已启用！");
        }
        categoryMapper.upEnableByIdQ(id);
        return JsonResult.ok("启用成功");
    }
    //3. 根据类别的id，隐藏（调整is_display的值）对应的类别（调整is_display的值）
//            - 类别不存在时抛出异常
//- 类别已隐藏时抛出异常
    public JsonResult concealById(Integer id) throws ServiceException {
        Integer display=categoryMapper.selectDisplayById(id);
        if (display==null){
            throw new ServiceException(State.ERR_UPDATE, "隐藏失败，该分类不存在！");
        }
        if (display==0){
            throw new ServiceException(State.ERR_UPDATE, "隐藏失败，该分类已隐藏！");
        }
        categoryMapper.upDisplayById(id);
        return JsonResult.ok("隐藏成功");
    }
    //4. 根据类别的id，显示（调整is_display的值）对应的类别
//- 类别不存在时抛出异常
//- 类别已显示时抛出异常
    public JsonResult showById(Integer id) throws ServiceException {
        Integer display=categoryMapper.selectDisplayById(id);
        if (display==null){
            throw new ServiceException(State.ERR_UPDATE, "显示失败，该分类不存在！");
        }
        if (display==1){
            throw new ServiceException(State.ERR_UPDATE, "显示失败，该分类已显示！");
        }
        categoryMapper.upDisplayByIdQ(id);
        return JsonResult.ok("显示成功");
    }
    //5. 根据类别的id，删除对应的类别
    public JsonResult deleteById(Integer id) throws ServiceException {
        CategorySimpleVO categorySimpleVO=categoryMapper.selectCategoryById(id);
        //- 类别不存在时抛出异常
        if (categorySimpleVO==null){
            throw new ServiceException(State.ERR_UPDATE,"删除失败，该分类不存在！");
        }
        Integer sonNumber=categoryMapper.selectSonNumberById(categorySimpleVO.getId());
        //- 类别存在子级类别时抛出异常
        if (sonNumber!=0){
            throw new ServiceException(State.ERR_UPDATE,"删除失败，该分类该分类还有子分类存在！");
        }
        //- 如果删除的类别是父级类别中的最后一个类别，删除成功后，父级类别的is_parent需更新为0）
        Integer parentSonNumber=categoryMapper.selectSonNumberById(categorySimpleVO.getParentId());
        categoryMapper.deleteById(id);
        if (parentSonNumber==1){
            categoryMapper.upIsParentToZeroById(categorySimpleVO.getParentId());
            return JsonResult.ok("删除成功，该类是父类的最后一个子类");
        }
        return JsonResult.ok("删除成功，该类不是父类的最后一个子类");
    }
    // 6. 根据类别的id，修改对应的类别的基本信息，包括：名称、关键字、图标、排序序号
//- 类别不存在时抛出异常
//- 新名称已经被占用时抛出异常
    public JsonResult updataById(CategorySimpleListItemVO categorySimpleListItemVO) throws ServiceException {
        CategorySimpleListItemVO categorySimpleListItemVO1=categoryMapper.selectById(categorySimpleListItemVO.getId());
        //查询传入id是否存在
        if (categorySimpleListItemVO1==null){
            throw new ServiceException(State.ERR_UPDATE,"修改失败，该分类不存在！");
        }
        //查询是否有分类名称重复与传入分类名称重复
        Integer nameNumder=categoryMapper.selectRepeatName(categorySimpleListItemVO.getId(),categorySimpleListItemVO.getName());
        System.out.println("nameNumder===="+nameNumder);
        if (nameNumder>=1){
            throw new ServiceException(State.ERR_UPDATE,"修改失败，分类名称有重复！");
        }
        categoryMapper.upCategory(categorySimpleListItemVO);
        return JsonResult.ok("修改成功");
    }
    //7. 重建缓存
//    当请求 /categories/cache/rebuild 路径时，将重建Redis缓存中的所有类别数据（与缓存预热相同的处理）
    public JsonResult onRedis(Integer id){return null;}
}
